<?php

namespace app\models;

use Yii;
use yii\db\Query;
use yii\helpers\Json;
use yii\db\Exception;
use yii\behaviors\TimestampBehavior;
use app\components\helpers\ArrayHelper;

/**
 * This is the model class for table "{{%position}}".
 *
 * @property int $id 主键
 * @property int $group_id 组织
 * @property int $dept_id 部门
 * @property int $parent_id 上级
 * @property string $name 名称
 * @property int $created_at 创建时间
 * @property int $updated_at 更新时间
 */
class Position extends ActiveRecord
{
    public function behaviors()
    {
        return [['class' => TimestampBehavior::class]];
    }

    public function getParent()
    {
        return $this->hasOne(Position::class, ['id' => 'parent_id']);
    }

    public function getDept()
    {
        return $this->hasOne(Department::class, ['id' => 'dept_id']);
    }

    public function getUsers()
    {
        return $this->hasMany(User::class, ['position_id' => 'id']);
    }

    /**
     * 下级岗位统计
     * @return bool|int|string|null
     */
    public function getChildrenCount()
    {
        return $this->hasMany(Position::class, ['parent_id' => 'id'])->count('id');
    }

    /**
     * 岗位下用户数量统计
     * @return bool|int|string|null
     */
    public function getUserCount()
    {
        return $this->hasMany(User::class, ['position_id' => 'id'])->count('id');
    }

    public function rules()
    {
        return [[['group_id', 'dept_id', 'parent_id', 'name'], 'safe']];
    }

    public static function tableName()
    {
        return '{{%position}}';
    }

    private function _makeUpItem($item, $auth, $data)
    {
        if (empty($item)) {
            return [];
        }
        $positionItem = [];
        $authData = [];

        if (!empty($auth)) {
            $authArr = Json::decode($auth);
            foreach ($authArr as $arr) {
                foreach ($arr as $i => $v) {
                    $authData[$i] = $v;
                }
            }
        }

        $dataArr = [];
        if (!empty($data)) {
            $dArr = Json::decode($data);
            foreach ($dArr as $arr) {
                foreach ($arr as $i => $v) {
                    $dataArr[$i] = $v;
                }
            }
        }

        foreach ($item as $i) {
            $positionItem[] = [
                'type' => isset($authData[$i]) ? $authData[$i] : 0,
                'position_id' => $this->id,
                'item_id' => $i,
                'data' => isset($dataArr[$i]) ? Json::encode($dataArr[$i]) : ''
            ];
        }
        return $positionItem;
    }

    /**
     * 添加 岗位
     * @param $attr
     * @return bool|void
     */
    public static function newCreate($attr)
    {
        $db = app()->getDb();
        $trans = $db->beginTransaction();
        try {
            $attr = ArrayHelper::humpToUnderline($attr);

            // 岗位
            $keys = ['group_id', 'dept_id', 'parent_id', 'name'];
            $arr = array_intersect_key($attr, array_flip($keys));
            $model = new self();
            $model->setAttributes($arr);
            $model->save(false);

            // 权限 & 默认权限
            $itemArr = $model->_makeUpItem($attr['item'], $attr['auth'], $attr['data']);
            $itemArr ? $model->addItem($itemArr, $db) : '';
            ($attr['set_default'] && $itemArr) ? $model->addDefaultItem($itemArr, $db) : '';

            // 添加上级岗位时、修改此岗位的上级为当前新增的岗位
            $attr['child_id'] ? self::updateByPk(['parent_id' => $model->id], $attr['child_id']) : '';

            $trans->commit();
        } catch (Exception $e) {
            $trans->rollBack();
            dump($e->getMessage());
        }
    }

    /**
     * 编辑 岗位
     * @param $attr
     */
    public static function performUpdate($attr)
    {
        $db = app()->getDb();
        $trans = $db->beginTransaction();
        try {

            $model = self::findOne($attr['id']);
            $model->parent_id = $attr['parentId'];
            $model->name = $attr['name'];
            $model->save(false);

            $itemArr = $model->_makeUpItem($attr['item'], $attr['auth'], $attr['data']);
            $model->removeItem($db);
            $itemArr ? $model->addItem($itemArr, $db) : '';
            if ($attr['setDefault']) {
                $model->removeDefaultItem($db);
                $itemArr ? $model->addDefaultItem($itemArr, $db) : '';
            }

            $trans->commit();
        } catch (Exception $e) {
            $trans->rollBack();
        }
    }

    /**
     * 删除 岗位
     * @param $attr
     * @throws \Throwable
     */
    public function performDelete()
    {
        $db = app()->getDb();
        $trans = $db->beginTransaction();
        try {

            $this->removeItem();
            $this->removeDefaultItem();
            $this->delete();

            $trans->commit();
        } catch (Exception $e) {

            dump($e->getMessage());

            $trans->rollBack();
        }
    }

    /**
     * 为岗位添加权限
     * @param $item
     * @param $db
     */
    public function addItem($item, $db)
    {
        $column = ['type', 'position_id', 'item_id', 'data'];
        $db->createCommand()
            ->batchInsert('{{%position_item}}', $column, $item)
            ->execute();
    }

    /**
     * 为岗位添加默认权限
     * @param $item
     * @param $db
     */
    public function addDefaultItem($item, $db)
    {
        $column = ['type', 'position_id', 'item_id', 'data'];
        $db->createCommand()
            ->batchInsert('{{%position_item_default}}', $column, $item)
            ->execute();
    }

    /**
     * 移除岗位权限
     * @param $db
     */
    public function removeItem()
    {
        PositionItem::deleteAll(['position_id' => $this->id]);
    }

    /**
     * 移除岗位默认权限
     * @param $db
     */
    public function removeDefaultItem()
    {
        PositionItemDefault::deleteAll(['position_id' => $this->id]);
    }

    /**
     * 查询某组织 & 某部门下的的岗位数据，并包含其下用户数量统计
     * @param $groupId
     * @param int $deptId
     * @return array|ActiveRecord[]
     */
    public static function getListWithUserCount($groupId, $deptId = 0)
    {
        // 子查询 用户统计
        $subQuery = UserProfile::find();
        $subQuery->select('COUNT(*)');
        $subQuery->where('u.position_id = p.id');
        $subQuery->asArray();
        $subQuery->alias('u');

        // 岗位查询
        $query = self::find();
        $query->select([
            'id',
            'parent_id AS parentId',
            'group_id AS groupId',
            'dept_id AS deptId',
            'name',
            'count' => $subQuery
        ]);
        $query->where(['group_id' => $groupId]);
        $deptId ? $query->andWhere(['dept_id' => $deptId]) : '';
        $query->asArray()->alias('p');
        return $query->all();
    }

    /**
     * 获取岗位详情
     * @param $id
     * @return array|\yii\db\ActiveRecord|null
     */
    public static function getViewById($id)
    {
        $query = self::find()->alias('p');
        $query->select(['p.name', 'd.name AS dept']);
        $query->leftJoin(Department::tableName() . ' d', 'd.id = p.dept_id');
        $query->where(['p.id' => $id]);
        return $query->one();
    }

    /**
     * 查询某组织 & 部门下的岗位数据
     * @param $groupId
     * @param $deptId
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getListByGroupIdAndDeptId($groupId, $deptId)
    {
        $query = self::find();
        $query->select(['id', 'parent_id AS parentId', 'name']);
        $query->where(['group_id' => $groupId, 'dept_id' => $deptId]);
        $query->asArray();
        return $query->all();
    }

    /**
     * 查询某组织 | 部门下的岗位数据
     * @param $groupId
     * @param $deptId
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getListByGroupIdOrDeptId($groupId = 0, $deptId = 0)
    {
        return self::getListWithUserCount($groupId, $deptId);
    }

    /**
     * 获取岗位已赋予的权限项
     * @param $id
     * @return array
     */
    public static function getOwnItemList($id)
    {
        $query = new Query();
        $query->select(['item_id AS id', 'type']);
        $query->from(PositionItem::tableName());
        $query->where(['position_id' => $id]);
        return $query->all();
    }

    /**
     * 获取岗位默认的权限项
     * @param $id
     * @return array
     */
    public static function getDefaultItem($id)
    {
        $query = new Query();
        $query->select(['item_id AS id', 'type']);
        $query->from(PositionItemDefault::tableName());
        $query->where(['position_id' => $id]);
        return $query->all();
    }

}
